package cn.springsoter.core.sms.service;

import cn.springsoter.core.sms.exception.SMSException;
import cn.springsoter.core.sms.model.dto.*;
import cn.springsoter.core.sms.model.vo.BaseSMSMessageVO;
import cn.springsoter.core.sms.model.vo.SMSMessageVO;

import java.util.List;

/**
 * 短信接口
 *
 * @author dws
 * @date 2022-09-06 17:30:00
 */
public interface ISMSService {

    /**
     * 给单个或多个手机号发送相同内容的普通短信
     * <p><em>回调注意事项：</em><p>
     *  1. {@link SMSMessageDTO#getCallbackUrlPre()} 为 {@code null} 时不回调
     *  2. 回调内容是一个列表，查看 {@link DaHanReportRequestDTO#getReports()} 了解详情 <p>
     *  3. 相同 {@code callbackUrl} 的多次请求，会在同一个回调请求中告知全部结果 <p>
     *  4. 该方法实现会组合 {@code callbackUrlPre+"/sms/callback/"+msgId}，作为 {@code callbackUrl}，
     *     这样每次回调请求的内容会和发送短信请求一一对应 <p>
     *  5. <em>特别注意如果是给多个号码 ({@link SMSMessageDTO#getPhones()}) 发送短信，
     *      回调通知会拆分成，同一个回调通知不同报告项 ({@link DaHanReportRequestDTO#getReports()},{@link DaHanReportDTO#getPhone()})，
     *      或者分多次回调通知每个手机号的发送情况
     *     </em><p>
     *  6. 回调采用post方式提交请求，{@code Content-Type="application/x-www-form-urlencoded;charset=UTF-8"}，接收key为report的值，内容参考 {@link DaHanReportRequestDTO}
     *     接收示例：
     *     <blockquote><pre>{@code
     *     @ResponseBody
     *     @RequestMapping(value = "/sms/callback/{msgId}")
     *     public DaHanReportVO callback (@PathVariable("msgId") String msgId, @RequestParam String report) {
     *         DaHanReportRequestDTO daHanPushReportDTO = smsService.processCallbackReport(report);
     *         if(daHanPushReportDTO == null) {
     *             return DaHanReportVO.FAIL;
     *         }
     *         List<DaHanReportDTO> reports = daHanPushReportDTO.getReports();
     *         if(reports==null || reports.isEmpty()) {
     *             return DaHanReportVO.FAIL;
     *         }
     *         // 业务处理
     *         return DaHanReportVO.SUCCESS;
     *     }
     *     }</pre></blockquote>
     * @param smsMessage    短信消息，参考 {@link SMSMessageDTO}
     * @return 提交到短信供应商是否成功，提交成功时，返回消息标识、回调地址等，参考 {@link SMSMessageVO}，失败时抛出 {@link SMSException} 异常
     * @throws SMSException 参数校验不通过或其他失败情况会抛出这个异常
     */
    SMSMessageVO sendSms(SMSMessageDTO smsMessage);

    /**
     * 给单个或多个手机号发送相同内容的营销短信
     * <p>非模板营销性质短信，每次发送都需要审核，建议使用模板发送营销短信 {@link #sendMarketingSms(SMSTemplateMessageDTO)}}
     * <p><em>回调注意事项：参考 {@link #sendSms(SMSMessageDTO)} 中的说明</em>
     * @param smsMessage    短信消息，参考{@link SMSMessageDTO}
     * @return 提交到短信供应商是否成功，提交成功时，返回消息标识、回调地址等，参考 {@link SMSMessageVO}，失败时抛出 {@link SMSException} 异常
     * @throws SMSException 参数校验不通过或其他失败情况会抛出这个异常
     */
    SMSMessageVO sendMarketingSms(SMSMessageDTO smsMessage);

     /**
     * 批量发送短信
     * @param smsMessages 短信配置参考 {@link BaseSMSMessageDTO}，注意列表最大1000条数据
     * @return 提交到短信供应商是否成功。
      * 提交成功时，返回消息标识，和入参顺序保持一致，参考 {@link BaseSMSMessageVO}。
      * 失败时抛出 {@link SMSException} 异常
     * @throws SMSException 参数校验不通过或其他失败情况会抛出这个异常
     */
    List<BaseSMSMessageVO> sendBatchSms(List<BaseSMSMessageDTO> smsMessages);

     /**
     * 批量发送营销短信
     * 非模板营销性质短信，每次发送都需要审核，建议使用模板发送营销短信 {@link #sendMarketingSms(SMSTemplateMessageDTO)}}
     * @param smsMessages 短信配置参考 {@link BaseSMSMessageDTO}，注意列表最大1000条数据
     * @return 提交到短信供应商是否成功。
      * 提交成功时，返回消息标识，和入参顺序保持一致，参考 {@link BaseSMSMessageVO}。
      * 失败时抛出 {@link SMSException} 异常
     * @throws SMSException 参数校验不通过或其他失败情况会抛出这个异常
     */
    List<BaseSMSMessageVO> sendBatchMarketingSms(List<BaseSMSMessageDTO> smsMessages);

     /**
     * 给单个或多个手机号发送普通模板短信
     * <p><em>回调注意事项：参考 {@link #sendSms(SMSMessageDTO)} 中的说明</em>
     * @param smsTemplateMessage 短信配置参考 {@link SMSTemplateMessageDTO}
     * @return 提交到短信供应商是否成功，提交成功时，返回消息标识、回调地址等，参考 {@link SMSMessageVO}，失败时抛出 {@link SMSException} 异常
     * @throws SMSException 参数校验不通过或其他失败情况会抛出这个异常
     */
     SMSMessageVO sendSms(SMSTemplateMessageDTO smsTemplateMessage);

     /**
     * 给单个或多个手机号发送营销模板短信
     * <p><em>回调注意事项：参考 {@link #sendSms(SMSMessageDTO)} 中的说明</em>
     * @param smsTemplateMessage 短信配置参考 {@link SMSTemplateMessageDTO}
     * @return 提交到短信供应商是否成功，提交成功时，返回消息标识、回调地址等，参考 {@link SMSMessageVO}，失败时抛出 {@link SMSException} 异常
     * @throws SMSException 参数校验不通过或其他失败情况会抛出这个异常
     */
     SMSMessageVO sendMarketingSms(SMSTemplateMessageDTO smsTemplateMessage);

    /**
     * 处理大汉三通回调通知
     * @param report 大汉三通回调json格式字符串
     * @return 大汉三通回调类对象
     */
    DaHanReportRequestDTO processCallbackReport(String report);
}
